﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
//using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
//using System.Xml.Linq;

namespace ServerControls
{
    [DefaultProperty("Text")]
    [ToolboxData("<{0}:Menu runat=server></{0}:Menu>")]
    public class Menu : WebControl
    {
        private string menuHTML = "";
        int level = 0;

        protected void Page_Load(object sender, EventArgs e)
        {
            //LoadSiteMapXml();
        }

        protected override void RenderContents(HtmlTextWriter output)
        {
            try
            {
                if (HttpContext.Current != null)
                {
                    if (HttpContext.Current.Request.IsAuthenticated == true)
                    {
                        menuHTML += "<ul class=\"nav\">";
                        generateMenu(LoadSiteMapXml());
                        menuHTML += "</ul>";
                        output.Write(menuHTML);
                    }
                }
                else//render in design mode.
                {
                    menuHTML += "<ul class=\"nav\">";
                    generateMenu(LoadSiteMapXml());
                    menuHTML += "</ul>";
                    output.Write(menuHTML);
                }
            }
            catch (Exception ex)
            {
                string lines = IsInDesignMode().ToString() + "  " + ex.ToString();

                // Write the string to a file.
                System.IO.StreamWriter file = new System.IO.StreamWriter("c:\\temp\\error.txt");
                file.WriteLine(lines);

                file.Close();
            }
        }

        [Bindable(true)]
        [Category("Control Property")]
        [DefaultValue("")]
        [Localizable(true)]
        public List<Attribute> AttributesForSelectedItem { get; set; }

        [Bindable(true)]
        [Category("Control Property")]
        [DefaultValue("")]
        [Localizable(true)]
        public List<Attribute> AttributesForItem { get; set; }

        [Bindable(true)]
        [Category("Control Property")]
        [DefaultValue("")]
        [Localizable(true)]
        public string SiteMapFileName { get; set; }

        [Bindable(true)]
        [Category("Control Property")]
        [DefaultValue("")]
        [Localizable(true)]
        public int SiteMapLevelToReadFrom { get; set; }

        public string SiteMapPhysicalPath { get; set; }

        public bool IsInDesignMode()
        {
            if (HttpContext.Current == null)
                return true;
            else
                return false;
        }

        private XmlNode LoadSiteMapXml()
        {
            try
            {

                bool isDesignTime = IsInDesignMode();
                string baseDir = "";

                XmlDocument siteMapXml = new XmlDocument();

                if (!isDesignTime)
                {
                    baseDir = AppDomain.CurrentDomain.BaseDirectory;
                    siteMapXml.Load(baseDir + SiteMapFileName);
                }
                else
                {
                    siteMapXml.Load(SiteMapPhysicalPath);
                }

                XmlNode node = siteMapXml.ChildNodes[SiteMapLevelToReadFrom];
                return node;
            }
            catch
            {
                return null;
            }
        }

        private void generateMenu(XmlNode doc)
        {
            level++;

            if (doc == null)
                return;

            if (doc.Name == "siteMapNode")
                if (!string.IsNullOrEmpty(doc.Attributes["title"].Value))
                    if (doc.ChildNodes.Count > 0)
                    {
                        menuHTML += "<ul class=\"dropdown-menu\">";
                    }

            foreach (XmlNode node in doc.ChildNodes)
            {
                if (node.Name == "siteMapNode")
                {
                    if (!string.IsNullOrEmpty(node.Attributes["title"].Value))
                    {
                        string title = string.IsNullOrEmpty(node.Attributes["title"].Value) ? "" : node.Attributes["title"].Value;
                        string url = string.IsNullOrEmpty(node.Attributes["url"].Value) ? "#" : node.Attributes["url"].Value;
                        string description = string.IsNullOrEmpty(node.Attributes["description"].Value) ? "" : node.Attributes["description"].Value;
                        if (node.ChildNodes.Count > 0)
                        {
                            int depth = getNodeLevel(url, title);

                            if (isChildSelected(node) == true)
                            {
                                if(depth >1)
                                    menuHTML += "<li class=\"dropdown-submenu active\"><a href=\"" + ResolveUrl(url) + "\" class=\"dropdown-toggle\" data-toggle=\"dropdown\">" + title + "</a>";
                                else
                                    menuHTML += "<li class=\"dropdown active\"><a href=\"" + ResolveUrl(url) + "\" class=\"dropdown-toggle\" data-toggle=\"dropdown\">" + title + "<b class=\"caret\"></b></a>";
                            }
                            else
                            {
                                if(depth > 1)
                                    menuHTML += "<li class=\"dropdown-submenu\"><a href=\"" + ResolveUrl(url) + "\" class=\"dropdown-toggle\" data-toggle=\"dropdown\">" + title + "</a>";
                                else
                                    menuHTML += "<li class=\"dropdown\"><a href=\"" + ResolveUrl(url) + "\" class=\"dropdown-toggle\" data-toggle=\"dropdown\">" + title + "<b class=\"caret\"></b></a>";
                            }

                            generateMenu(node);
                            menuHTML += "</li>";
                        }
                        else
                        {
                            if ((HttpContext.Current == null ? "----" : HttpContext.Current.Request.Url.AbsolutePath) == ResolveUrl(url))
                            {
                                menuHTML += "<li class=\"active\"><a style=\"cursor: default;\">" + title + "</a></li>";
                            }
                            else
                                menuHTML += "<li><a href=\"" + ResolveUrl(url) + "\">" + title + "</a></li>";

                            generateMenu(node);
                        }
                    }
                    else
                        generateMenu(node);
                }
            }

            if (doc.Name == "siteMapNode")
                if (!string.IsNullOrEmpty(doc.Attributes["title"].Value))
                    if (doc.ChildNodes.Count > 0)
                        menuHTML += "</ul>";
        }


        private bool isChildSelected(XmlNode node)
        {
            if (HttpContext.Current == null)
                return false;

            bool ret = false;
            foreach (XmlNode cn in node.ChildNodes)
            {
                if (!string.IsNullOrEmpty(cn.Attributes["title"].Value))
                {
                    string url = string.IsNullOrEmpty(cn.Attributes["url"].Value) ? "#" : cn.Attributes["url"].Value;

                    if (HttpContext.Current.Request.Url.AbsolutePath == ResolveUrl(url))
                    {
                        ret = true;
                        break;
                    }
                }

                if (isChildSelected(cn) == true)
                {
                    ret = true;
                    break;
                }
            }
            return ret;
        }

        private int getNodeLevel(string url, string title)
        {
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            XmlTextReader reader = new XmlTextReader(baseDir + SiteMapFileName);
            int level = 0;
            while (reader.Read())
            {
                if (reader.GetAttribute("url") != null && reader.GetAttribute("title") !=null)
                {
                    if (reader.GetAttribute("url") == url && reader.GetAttribute("title") == title)
                    {
                        level = reader.Depth;
                        break;
                    }
                }
            }
            reader.Close();
            return level-1;
        }
    }

    public class Attribute
    {
        public string Key {get; set; }
        public string Value { get; set; }
    }
}
